package com.taobao.askwho.utils;
import java.io.IOException;
import java.net.MalformedURLException;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collection;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
import org.apache.solr.client.solrj.impl.XMLResponseParser;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrInputDocument;

public class SolrUtil
{
	private static int fetchSize = 1000;
	private static String url = "http://localhost:8983/solr/";
	private static CommonsHttpSolrServer solrCore;
	private static SolrUtil util = null;
	
	public static final String SOLOR_INDEX = "tagname";
	public static final int QUERY_NORMAL_NUMBER = 30;
	public static final int QUERY_LARGE_NUMBER = 100;
	
	private SolrUtil() throws MalformedURLException
	{
		solrCore = new CommonsHttpSolrServer(url);
		solrCore.setSoTimeout(1000);  // socket read timeout
		solrCore.setConnectionTimeout(100);
		solrCore.setDefaultMaxConnectionsPerHost(100);
		solrCore.setMaxTotalConnections(100);
		solrCore.setFollowRedirects(false);  // defaults to false
		// allowCompression defaults to false.
		// solrCore side must support gzip or deflate for this to have any effect.
		solrCore.setAllowCompression(true);
		solrCore.setMaxRetries(1); // defaults to 0.  > 1 not recommended.
		solrCore.setParser(new XMLResponseParser()); // binary parser is used by default
	}

	public static SolrUtil get() throws MalformedURLException {
		if(util == null) {
			util = new SolrUtil();
		}
		return util;
	}
	
	public void deleteAllIndex() throws SolrServerException, IOException {
		solrCore.deleteByQuery( "*:*" );// CAUTION: deletes everything!
	}
	
	/**
	 * 从solr查询返回的信息
	 * @param column 查询的key
	 * @param query 查询的值
	 * @param limit
	 * @return
	 * @throws SolrServerException
	 */
	public QueryResponse querySingleColumn(String column, String query, int limit) throws SolrServerException {
		SolrQuery solrQuery = new  SolrQuery().
				setQuery(query).
				//setFacet(true).
				//setFacetMinCount(1).
				//setFacetLimit(limit).
				//addFacetField(column)
				setStart(0).	//未来支持分页，预留
				setRows(limit);
		return solrCore.query(solrQuery);
	}
	
	/**
	 * Takes an SQL ResultSet and adds the documents to solr. Does it in batches
	 * of fetchSize.
	 * 
	 * @param rs
	 *            A ResultSet from the database.
	 * @return The number of documents added to solr.
	 * @throws SQLException
	 * @throws SolrServerException
	 * @throws IOException
	 */
	public long addResultSet(ResultSet rs) throws SQLException,
	SolrServerException, IOException
	{
		long count = 0;
		int innerCount = 0;
		Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
		ResultSetMetaData rsm = rs.getMetaData();
		int numColumns = rsm.getColumnCount();
		String[] colNames = new String[numColumns + 1];

		/**
		 * JDBC numbers the columns starting at 1, so the normal java convention
		 * of starting at zero won't work.
		 */
		for (int i = 1; i < (numColumns + 1); i++)
		{
			colNames[i] = rsm.getColumnName(i);
			/**
			 * If there are fields that you want to handle manually, check for
			 * them here and change that entry in colNames to null. This will
			 * cause the loop in the next section to skip that database column.
			 */
			// //Example:
			// if (rsm.getColumnName(i) == "db_id")
			// {
			// colNames[i] = null;
			// }
		}

		while (rs.next())
		{
			count++;
			innerCount++;

			SolrInputDocument doc = new SolrInputDocument();

			/**
			 * At this point, take care of manual document field assignments for
			 * which you previously assigned the colNames entry to null.
			 */
			// //Example:
			// doc.addField("solr_db_id", rs.getLong("db_id"));

			for (int j = 1; j < (numColumns + 1); j++)
			{
				if (colNames[j] != null)
				{
					Object f;
					switch (rsm.getColumnType(j))
					{
					case Types.BIGINT:
					{
						f = rs.getLong(j);
						break;
					}
					case Types.INTEGER:
					{
						f = rs.getInt(j);
						break;
					}
					case Types.DATE:
					{
						f = rs.getDate(j);
						break;
					}
					case Types.FLOAT:
					{
						f = rs.getFloat(j);
						break;
					}
					case Types.DOUBLE:
					{
						f = rs.getDouble(j);
						break;
					}
					case Types.TIME:
					{
						f = rs.getDate(j);
						break;
					}
					case Types.BOOLEAN:
					{
						f = rs.getBoolean(j);
						break;
					}
					default:
					{
						f = rs.getString(j);
					}
					}
					doc.addField(colNames[j], f);
				}
			}
			docs.add(doc);

			/**
			 * When we reach fetchSize, index the documents and reset the inner
			 * counter.
			 */
			if (innerCount == fetchSize)
			{
				solrCore.add(docs);
				docs.clear();
				innerCount = 0;
			}
		}

		/**
		 * If the outer loop ended before the inner loop reset, index the
		 * remaining documents.
		 */
		if (innerCount != 0)
		{
			solrCore.add(docs);
		}
		return count;
	}
}